package com.skt.controller;

import com.skt.domain.DTO.LoginDTO;
import com.skt.domain.DTO.request.ChangePasswordRequest;
import com.skt.domain.DTO.request.UpdateProfileRequest;
import com.skt.domain.VO.UserVO;
import com.skt.service.UserService;
import com.skt.utils.JwtUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Collections;

@RestController // 表明这是一个返回 JSON 的控制器
@RequestMapping("/user") // 设置基础路径为 /user
@Tag(name = "用户接口") // 用于 Swagger 文档分组
@RequiredArgsConstructor // 自动生成含 final 依赖字段的构造函数，实现自动注入
public class UserController {

    private final UserService userService;

    private final JwtUtil jwtUtil;

    @Operation(summary = "用户登录") // 在 Swagger/OpenAPI 文档中，将此接口标记为“用户登录”，用于接口说明
    @PostMapping("/login") // 定义这是一个 POST 请求，路径为 /user/login
    public UserVO login(@Valid @RequestBody LoginDTO loginDTO) {
        // @Valid: 触发对 被注解的 Java 对象进行参数校验
        // @RequestBody: 把 HTTP 请求体（Request Body）中的 JSON 数据，自动反序列化为 Java 对象。
        return userService.login(loginDTO);
    }


    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public UserVO register(@Valid @RequestBody LoginDTO loginDTO) {
        return userService.register(loginDTO);
    }


    @Operation(summary = "获取用户信息")
    @GetMapping("/me")
    public UserVO getUserInfo() {
        return userService.getCurrentUser();
    }


    @GetMapping("/test")
    public String test(@RequestParam(required = false) String token) {
        // 如果提供了 token 参数，尝试手动认证（仅用于调试！）
        if (token != null && !token.trim().isEmpty()) {
            if (jwtUtil.validateToken(token)) {
                String username = jwtUtil.getUsernameFromToken(token);
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList());
                SecurityContextHolder.getContext().setAuthentication(authentication);
                return "✅ 通过 token 参数认证成功！当前用户: " + username;
            } else {
                return "❌ 提供的 token 无效或已过期";
            }
        }

        // 正常走 SecurityContext（由 JwtAuthenticationFilter 设置）
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null && auth.isAuthenticated() && !"anonymousUser".equals(auth.getName())) {
            return "🔒 正常认证成功！当前用户: " + auth.getName();
        }

        return "❌ 未认证（anonymousUser）";
    }


    @Operation(summary = "更新个人资料")
    @PutMapping("/profile")
    @PreAuthorize("isAuthenticated()") // 强制要求用户已登录
    public UserVO updateOwnProfile(@Valid @RequestBody UpdateProfileRequest updateProfileRequest) {
        return userService.updateOwnProfile(updateProfileRequest);
    }


    @Operation(summary = "修改密码")
    @PostMapping("/change-password")
    @PreAuthorize("isAuthenticated()") // 强制要求用户已登录
    public ResponseEntity<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
        userService.changePassword(request);
        /*
        ResponseEntity：Spring 封装 HTTP 响应的类（包含状态码、头、体）。
        .noContent()：静态方法，创建一个 状态码为 204 的响应构建器。
        .build()：生成最终的 ResponseEntity<Void> 对象。
         */
        return ResponseEntity.noContent().build();
    }
}


/**
 *
 * http://localhost:8080/v3/api-docs
 *
 * 状态码	名称	含义说明	典型使用场景
 * 200	OK	请求成功	查询、登录、更新成功返回数据
 * 201	Created	资源创建成功	用户注册、新增数据成功
 * 204	No Content	请求成功，无返回内容	删除成功、更新成功但无需返
 * 400	Bad Request	客户端请求错误（参数无效/格式错误）	表单校验失败、JSON 解析错误
 * 401	Unauthorized	未认证（缺少或无效身份凭证）	Token 无效、未登录
 * 403	Forbidden	已认证，但无权限访问	普通用户访问管理员接口
 * 404	Not Found	请求的资源不存在	ID 不存在、访问错误 URL
 * 409	Conflict	请求冲突	用户名/邮箱已存在
 * 500	Internal Server Error	服务器内部错误	代码异常（空指针、数据库异常等）
 */